package com.googlecode.stemwijzer.server.rest;

import java.io.IOException;

import javax.annotation.Resource;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlecode.stemwijzer.client.StemwijzerService;
import com.googlecode.stemwijzer.shared.model.IsAnswer;
import com.googlecode.stemwijzer.shared.model.IsQuestion;
import com.googlecode.stemwijzer.shared.model.impl.Answer;
import com.googlecode.stemwijzer.shared.model.impl.Question;
import com.sun.jersey.api.json.JSONWithPadding;

/**
 * The class StemwijzerRestServlet.
 * 
 * @author j.brosens (RemoteServlet, Method implementation), roel.hodzelmans (Rest annotations).
 */
@Singleton
@Resource
@Path("/public")
public class StemwijzerRestServlet {

	/** Constant for the JSONP media type. */
	protected static final String APPLICATION_JSONP = "application/x-javascript";

	/** Constant for the user name parameter. */
	protected static final String USERNAME_PATHPARAM = "userName";

	/** Jackson Object mapper. */
	protected ObjectMapper mapper;

	/** The actual service implementation */
	protected StemwijzerService service;

	/**
	 * Constructor with reference to session.
	 * 
	 * @param session
	 *            Bean containing state.
	 */
	@Inject
	public StemwijzerRestServlet(final StemwijzerService service, final ObjectMapper mapper) {
		this.service = service;
		this.mapper = mapper;
	}

	@GET
	@Path("/result")
	@Produces( { APPLICATION_JSONP })
	public JSONWithPadding getResult(@QueryParam("callback") @DefaultValue("callback") final String callback)
			throws JsonGenerationException, JsonMappingException, IOException {
		System.out.println("Received JSONP request on [getResult]");

		return new JSONWithPadding(this.mapper.writeValueAsString(this.service.getResult()), callback);
	}

	@GET
	@Path("/register/{" + USERNAME_PATHPARAM + "}")
	@Produces( { APPLICATION_JSONP })
	public JSONWithPadding registerUser(@PathParam(USERNAME_PATHPARAM) final String userName,
			@QueryParam("callback") @DefaultValue("callback") final String callback) throws JsonGenerationException,
			JsonMappingException, IOException {
		System.out.println("Received JSONP request on [registerUser]");

		return new JSONWithPadding(this.mapper.writeValueAsString(this.service.registerUser(userName)), callback);
	}

	@GET
	@Path("/resetsession")
	@Produces( { APPLICATION_JSONP })
	public JSONWithPadding resetSession(@QueryParam("callback") @DefaultValue("callback") final String callback)
			throws JsonGenerationException, JsonMappingException, IOException {
		System.out.println("Received JSONP request on [resetSession]");

		return new JSONWithPadding(this.mapper.writeValueAsString(this.service.resetSession()), callback);
	}

	@GET
	@Path("/sendanswer")
	@Produces( { APPLICATION_JSONP })
	public JSONWithPadding sendAnswer(@QueryParam("question") final String question,
			@QueryParam("answer") final String answer,
			@QueryParam("callback") @DefaultValue("callback") final String callback) throws JsonGenerationException,
			JsonMappingException, IOException {
		System.out.println("Received JSONP request on [sendAnswer]");

		IsQuestion q = this.mapper.readValue(question, Question.class);
		IsAnswer a = this.mapper.readValue(question, Answer.class);

		return new JSONWithPadding(this.mapper.writeValueAsString(this.service.sendAnswer(q, a)), callback);
	}
}
